﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using DcsGauges.DataStructures;
using DcsGauges.Gui.Rendering;
using DcsGauges.Gui.Gauges.Interfaces;
using Microsoft.Xna.Framework;
using DcsGauges.Shared.DataStructures;
using DcsGauges.Gui.Gauges.ValueConverters;

namespace DcsGauges.Gui.Gauges
{
    class AnalogNumberGauge : GuiRenderableBase, IValueGauge
    {
        private readonly Point      renderTextureSize                           = new Point(120, 240);

        private const float         RotOffsetToZero                             = 115.0f;
        private const float         CameraPosZ                                  = -50.0f;

        private Model               numbersCylinder                             = null;
        private RenderTarget2D      renderTarget                                = null;
        private Texture2D           renderTexture                               = null;
        private DcsProperty        property                                    = null;
        private IGaugeValueConverter<float> converter                           = new LinearConverter(new InOutMapping(0.0f, MathEx.Deg2Rad(0.0f)), new InOutMapping(1.0f, MathEx.Deg2Rad(360.0f)));

        public AnalogNumberGauge(GuiRenderableBase parent, GraphicsDevice device, URect area, DcsProperty property, IGaugeValueConverter<float> conv) : base(parent, area)
        {
            PresentationParameters pp           = device.PresentationParameters;
            this.renderTarget                   = new RenderTarget2D(device, renderTextureSize.X, renderTextureSize.Y, true, device.DisplayMode.Format, DepthFormat.Depth24);
            this.numbersCylinder                = ModelManager.GetModel("Models/AnalogNumbersCylinder");
            this.property                       = property;
            this.converter                      = conv;
        }

        public override void Render(SpriteBatch spriteBatch, GraphicsDevice device, Rectangle parentRect, float globalZIndex)
        {
            this.renderTexture                  = this.RenderAnlogNumberTexture(device);
            Rectangle viewportRect              = this.CalcViewportRect(parentRect);
            spriteBatch.Draw(this.renderTexture, viewportRect, null, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, globalZIndex);
            device.SetRenderTarget(null);
        }

        private Texture2D RenderAnlogNumberTexture(GraphicsDevice device)
        {
            device.SetRenderTarget(this.renderTarget);
            device.Clear(Color.Black);

            Matrix projection                       = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(40.0f), (float)this.renderTextureSize.X / (float)this.renderTextureSize.Y, 0.1f, 1000.0f);
            Matrix view                             = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, CameraPosZ), Vector3.Zero, Vector3.Up); 

            foreach(var mesh in this.numbersCylinder.Meshes)
            {
                foreach(BasicEffect effect in mesh.Effects)
                {
                    //effect.EnableDefaultLighting();

                    effect.View         = view;
                    effect.Projection   = projection;
                    float byValueRot    = converter.Convert(this.Value);
                    effect.World        = Matrix.CreateRotationZ(MathEx.Deg2Rad(180.0f)) * Matrix.CreateRotationX(MathEx.Deg2Rad(RotOffsetToZero) + byValueRot) * Matrix.CreateTranslation(new Vector3(10, 0, 0)); //clear exporting errors by applying matrics (FBX export simply sucks :( )
                }
                mesh.Draw();
            }
            
            Texture2D rendered = (Texture2D)this.renderTarget;
            device.SetRenderTarget(null);
            return rendered;
        }


        public Shared.DataStructures.DcsProperty DataProperty
        {
            get { return this.property; }
        }

        public float Value { get; set; }
        
    }
}
